//#pragma once
#ifndef FIFO_HPP

#define FIFO_HPP

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define FIFO_FILE "./fifo"

// #define EXIT_FAILURE 1

// #define ERR_EXIT(m)         \
//     do                      \
//     {                       \
//         perror(m);          \
//         exit(EXIT_FAILURE); \
//     } while (0)

// #define ERR_EXIT(m)          \
//     do                       \
//     {                        \
//         perror(m);           \
//         exit(EXIT_FAILURE);  \
//     } while(0)

// #define PATH "."

//const int gmode = 0666;

class Fifo_Make
{
private:

public:
    Fifo_Make(std::string s)
        :_path(PATH)
        ,_name(s)
        //,_usertype(user)
    {
        _filena = _path + "/" + _name;
        // Create(_filena.c_str());
        // if(_usertype == CREATER)
        // {
        //     _filena = _path + "/" + _name;
        //     Create(_filena.c_str());
        // }
    }

    ~Fifo_Make()
    {
        //if(_usertype == CREATER)
        Close();
    }

    void Create()
    {
        int ret = mkfifo(_filena.c_str(), gmode);

        if (ret < 0)
        {
            ERR_EXIT("mkfifo");
        }
    }

    void Close()
    {
        unlink(_filena.c_str());
    }

    const char *str()
    {
        return _filena.c_str();
    }

private:
    std::string _path;
    std::string _name;
    std::string _filena;
    //std::string _usertype;
};

class Fifo_Oper
{
public:
    Fifo_Oper(const char* s)
        : _fifona(s)
    {
        // O_CREAT | O_WRONLY | O_RDONLY
        // only选项互不兼容。
        _fd = open(_fifona.c_str(), O_CREAT | O_RDWR, gmode);
        if (_fd < 0)
        {
            ERR_EXIT("open");
        }
    }

    ~Fifo_Oper()
    {
        close(_fd);
        //unlink(_str.c_str());
    }

    // 等待函数。（读取信号）
    bool Wait()
    {
        char c = 0;

        int number = 0;
        
        while(number == 0)
        {
            number = read(_fd,&c,1);

            if(number > 0)
            {
                std::cout << "Read Success" << std::endl;
                return true;
            }
        }
        
        if(number < 0)
        {
            return false;
        }
    }

    // 唤醒函数。（写入信号）
    void WakeUp()
    {
        char c = 'B';

        int n = write(_fd,&c,1);

        if(n < 0)
        {
            ERR_EXIT("write");
        }
    }

    void Close()
    {
        close(_fd);
    }

private:
    std::string _fifona;
    int _fd;
};

#endif